package com.wchen.gdoc.generate.resource.analysis;

import com.sun.javadoc.*;
import com.wchen.gdoc.generate.config.ApplicationConfigProvide;
import com.wchen.gdoc.generate.resource.structure.AnnotationStructure;
import com.wchen.gdoc.generate.resource.structure.FieldStructure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;


/**
 * 抽象解析
 *
 * @author  wchen
 * @date    2019/11/7
 */
public abstract class AbsParentAnalysis {
    public final static Logger LOGGER = LoggerFactory.getLogger(AbsParentAnalysis.class);
    public final static Boolean ENABLE_DEBUG = ApplicationConfigProvide.enableDebug();

    /**
     * 解析注解
     * @param annotationDescriptions   注解描述数组
     * @return
     */
    protected List<AnnotationStructure> analysisAnnotationDoc(AnnotationDesc[] annotationDescriptions){
        List<AnnotationStructure> annotationStructures = new ArrayList<>();
        for (AnnotationDesc annotationDesc : annotationDescriptions) {
            //取注解类型
            Set<String> annotationTypeSet = new HashSet<>();
            AnnotationDesc[] innerAnnotationDescs = annotationDesc.annotationType().annotations();
            for (AnnotationDesc innerAnnotationDesc : innerAnnotationDescs) {
                //注解类型
                String innerAnnotationType = innerAnnotationDesc.annotationType().toString();
                annotationTypeSet.add(innerAnnotationType);
            }

            //取注解配置值
            Map<String, String> elementMap = new HashMap<>();
            AnnotationDesc.ElementValuePair[] elementValuePairs = annotationDesc.elementValues();
            for (AnnotationDesc.ElementValuePair elementValuePair : elementValuePairs) {
                AnnotationTypeElementDoc annotationTypeElementDocs = elementValuePair.element();
                //注解定义的方法名
                String elementName = annotationTypeElementDocs.name();
                //注解值
                String elementValue = elementValuePair.value().toString().replaceAll("\"", "");
                elementMap.put(elementName, elementValue);
            }
            String annotationType = annotationDesc.annotationType().toString();
            annotationTypeSet.add(annotationType);
            AnnotationStructure annotationStructure = new AnnotationStructure();
            annotationStructure.setType(annotationType);
            annotationStructure.setElementMap(elementMap);
            annotationStructure.setElementType(annotationTypeSet);
            annotationStructures.add(annotationStructure);
        }
        return annotationStructures;
    }

    /**
     * 执行doc字段解析器链
     * @param docType
     * @param isRequestParam
     * @return
     */
    protected FieldStructure executeAnalysis(Type docType, Boolean isRequestParam){
        List<DocTypeAnalysis> absParentAnalysisList = ApplicationConfigProvide.getApplicationConfig().getDocTypeAnalysisChain();
        for (DocTypeAnalysis docTypeAnalysis : absParentAnalysisList) {
            if(docTypeAnalysis.isSupport(docType)){
                return docTypeAnalysis.analysisParam(docType, isRequestParam);
            }
        }
        return null;
    }

    /**
     * 提取泛型对象
     * @param docType
     * @return
     */
    protected Type extractGenericType(Type docType){
        ParameterizedType parameterizedType= docType.asParameterizedType();
        if(Objects.isNull(parameterizedType)){
            return null;
        }
        Type[] types = parameterizedType.typeArguments();

        if(types.length > 0){
            return types[0];
        }
        return null;
    }

}
